package com.wing.product.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wing.chanjet.entity.inventory.InventoryClassResponse;
import com.wing.chanjet.entity.warehouse.response.WarehouseQueryResponse;
import com.wing.chanjet.feign.ChanjetClient;
import com.wing.common.utils.JsonResult;
import com.wing.product.dao.ProductCategoryDao;
import com.wing.product.model.entity.ProductCategory;
import com.wing.product.model.request.ProductCategoryForm;
import com.wing.product.model.response.NodeDataVO;
import com.wing.product.model.response.ProductCategoryVO;
import com.wing.web.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 产品分类-ServiceImpl
 *
 * @author
 */
@Service
@Slf4j
public class ProductCategoryServiceImpl extends ServiceImpl<ProductCategoryDao, ProductCategory> implements ProductCategoryService {

    @Override
    public int add(ProductCategoryForm productCategoryForm) {

        //校验
        ProductCategory productCategory = new ProductCategory();
        CopyOptions copyOptions = CopyOptions.create().setEditable(ProductCategory.class).setIgnoreError(true).setIgnoreNullValue(true);
        BeanUtil.copyProperties(productCategoryForm, productCategory, copyOptions);
        if (productCategoryForm.getParentId() != -1) {
            ProductCategory productCategoryParent = new ProductCategory();
            productCategoryParent.setId(productCategoryForm.getParentId());
            productCategoryParent.setHasChild(true);
            if (productCategoryForm.getIsDeleted()) {
                productCategoryParent.setHasEnableChild(true);
            }
            baseMapper.updateById(productCategoryParent);
        }
        return baseMapper.insert(productCategory);
    }

    @Override
    public List<ProductCategoryVO> list4app(Map<String, Object> params) {
        return baseMapper.list4app(params);
    }

    @Override
    public Page<ProductCategoryVO> pageList4app(Page page, Map<String, Object> params) {
        List<ProductCategoryVO> list = baseMapper.list4app(page, params);
        page.setRecords(list);
        return page;
    }

    @Override
    public ProductCategoryVO get4appById(Long id) {
        return baseMapper.get4appById(id);
    }

    @Override
    @Transactional
    public int del(Long id) {
        ProductCategoryVO productCategoryVO = baseMapper.get4appById(id);
        if (productCategoryVO != null) {
            int delCount = baseMapper.deleteById(id);
            int count = baseMapper.selectCount(new QueryWrapper<ProductCategory>().eq("parent_id", productCategoryVO.getParentId()));
            if (count == 0) {
                ProductCategory productCategoryParent = new ProductCategory();
                productCategoryParent.setId(productCategoryVO.getParentId());
                productCategoryParent.setHasChild(false);
                productCategoryParent.setHasEnableChild(false);
                baseMapper.updateById(productCategoryParent);
            }
            return delCount;
        }
        return 0;
    }

    @Override
    @Transactional
    public int enable(Long id) {
        ProductCategoryVO productCategoryVO = baseMapper.get4appById(id);
        if (productCategoryVO != null) {
            ProductCategory productCategory = new ProductCategory();
            productCategory.setId(id);
            productCategory.setIsDeleted(true);
            int updateCount = baseMapper.updateById(productCategory);
            ProductCategory productCategoryParent = new ProductCategory();
            productCategoryParent.setId(productCategoryVO.getParentId());
            productCategoryParent.setHasEnableChild(true);
            baseMapper.updateById(productCategoryParent);
            return updateCount;
        }

        return 0;
    }

    @Override
    @Transactional
    public int disable(Long id) {
        ProductCategoryVO productCategoryVO = baseMapper.get4appById(id);
        if (productCategoryVO != null) {
            ProductCategory productCategory = new ProductCategory();
            productCategory.setId(id);
            productCategory.setIsDeleted(false);
            int updateCount = baseMapper.updateById(productCategory);
            int count = baseMapper.selectCount(new QueryWrapper<ProductCategory>().eq("parent_id", productCategoryVO.getParentId()).eq("is_deleted", true));
            if (count == 0) {
                ProductCategory productCategoryParent = new ProductCategory();
                productCategoryParent.setId(productCategoryVO.getParentId());
                productCategoryParent.setHasEnableChild(false);
                baseMapper.updateById(productCategoryParent);
            }
            return updateCount;
        }

        return 0;
    }

    @Override
    @Transactional
    public int update(ProductCategoryForm productCategoryForm) {
        ProductCategoryVO productCategoryVO = baseMapper.get4appById(productCategoryForm.getId());
        if (productCategoryVO != null) {
            if (!productCategoryVO.getParentId().equals(productCategoryForm.getParentId())) {
                boolean isUpdateEnable = productCategoryVO.getIsDeleted().equals(productCategoryForm.getIsDeleted());
                ProductCategory productCategory = new ProductCategory();
                BeanUtils.copyProperties(productCategoryForm, productCategory);
                baseMapper.updateById(productCategory);

                //update new parent category
                ProductCategory parentProductCategory = new ProductCategory();
                parentProductCategory.setId(productCategoryForm.getParentId());
                parentProductCategory.setHasChild(true);
                if (productCategoryForm.getIsDeleted()) {
                    parentProductCategory.setHasEnableChild(true);
                }
                baseMapper.updateById(parentProductCategory);

                //update current db product category
                int count = baseMapper.selectCount(new QueryWrapper<ProductCategory>().eq("parent_id", productCategoryVO.getParentId()));
                if (count == 0) {
                    ProductCategory productCategoryParent = new ProductCategory();
                    productCategoryParent.setId(productCategoryVO.getParentId());
                    productCategoryParent.setHasChild(false);
                    baseMapper.updateById(productCategoryParent);
                }
//                if (isUpdateEnable&&!productCategoryForm.getIsDeleted()){
                count = baseMapper.selectCount(new QueryWrapper<ProductCategory>().eq("parent_id", productCategoryVO.getParentId()).eq("is_deleted", true));
                if (count == 0) {
                    ProductCategory productCategoryParent = new ProductCategory();
                    productCategoryParent.setId(productCategoryVO.getParentId());
                    productCategoryParent.setHasEnableChild(false);
                    baseMapper.updateById(productCategoryParent);
                }
//                }
            } else {
                boolean isUpdateEnable = productCategoryVO.getIsDeleted().equals(productCategoryForm.getIsDeleted());
                ProductCategory productCategory = new ProductCategory();
                BeanUtils.copyProperties(productCategoryForm, productCategory);
                baseMapper.updateById(productCategory);
                if (isUpdateEnable && !productCategoryForm.getIsDeleted()) {
                    int count = baseMapper.selectCount(new QueryWrapper<ProductCategory>().eq("parent_id", productCategoryVO.getParentId()).eq("is_deleted", true));
                    if (count == 0) {
                        ProductCategory productCategoryParent = new ProductCategory();
                        productCategoryParent.setId(productCategoryVO.getParentId());
                        productCategoryParent.setHasEnableChild(false);
                        baseMapper.updateById(productCategoryParent);
                    }
                }

            }
        }
        return 0;
    }

    public JsonResult getTreeData() {
        Map paramMap = new HashMap();
        paramMap.put("dataSourceType", ProductCategory.DataSourceType.enterprise.getValue());
        List<ProductCategoryVO> list = baseMapper.list4app(paramMap);
        Map<Long, List<NodeDataVO>> map = new HashMap<>();
        for (ProductCategoryVO category : list) {
            if (map.containsKey(category.getParentId())) {
                NodeDataVO nodeDataVO = new NodeDataVO();
                nodeDataVO.setValue(category.getId().toString());
                nodeDataVO.setName(category.getName());
                map.get(category.getParentId()).add(nodeDataVO);
            } else {
                List<NodeDataVO> tmpList = new ArrayList<>();
                NodeDataVO nodeDataVO = new NodeDataVO();
                nodeDataVO.setValue(category.getId().toString());
                nodeDataVO.setName(category.getName());
                tmpList.add(nodeDataVO);
                map.put(category.getParentId(), tmpList);
            }
        }
        List<NodeDataVO> rootList = map.get(-1L);
        if (rootList == null) {
            return JsonResult.success();
        }
        constructTree(rootList, map);
        return JsonResult.success(rootList);
    }

    private void constructTree(List<NodeDataVO> parentList, Map<Long, List<NodeDataVO>> dataMap) {
        for (NodeDataVO node : parentList) {
            Long nodeId = Long.valueOf(node.getValue());
            List<NodeDataVO> childList = dataMap.get(nodeId);
            if (childList != null) {
                node.setChildren(childList);
                constructTree(childList, dataMap);
            }
        }
    }

    @Resource
    ChanjetClient chanjetClient;

    @Override
    public void chanjetInventoryClassSync() {
        List<ProductCategory> list = this.list();

        //存货分类列表
        JsonResult<List<InventoryClassResponse>> jsonResult = chanjetClient.inventoryClassQuery();
        if (jsonResult.getCode() == 200) {
            List<InventoryClassResponse> inventoryClassList = jsonResult.getData();
            for (InventoryClassResponse inventoryClass : inventoryClassList) {
                ProductCategory productCategory = new ProductCategory();
                productCategory.setIsDeleted(true);
                productCategory.setName(inventoryClass.getCode()+"-"+inventoryClass.getName());
                productCategory.setIsFinal(inventoryClass.isIsendnode());
                productCategory.setSortNumber(1);
                productCategory.setHasChild(false);
                productCategory.setHasEnableChild(false);
                productCategory.setStatus(ProductCategory.Status.created);
                productCategory.setDataSourceType(ProductCategory.DataSourceType.enterprise);
                if(inventoryClass.getParent() != null){
                    QueryWrapper<ProductCategory> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("name",inventoryClass.getParent().getCode()+"-"+inventoryClass.getParent().getName());
                    ProductCategory parentProductCategory = this.getOne(queryWrapper);
                    if(parentProductCategory != null){
                        productCategory.setParentId(parentProductCategory.getId());
                    }else{
                        parentProductCategory = new ProductCategory();
                        productCategory.setIsDeleted(true);
                        parentProductCategory.setName(inventoryClass.getParent().getCode()+"-"+inventoryClass.getParent().getName());
                        parentProductCategory.setIsFinal(inventoryClass.isIsendnode());
                        parentProductCategory.setSortNumber(1);
                        parentProductCategory.setHasChild(false);
                        parentProductCategory.setHasEnableChild(false);
                        parentProductCategory.setStatus(ProductCategory.Status.created);
                        parentProductCategory.setDataSourceType(ProductCategory.DataSourceType.enterprise);
                        parentProductCategory.setCreateTime(LocalDateTime.now());
                        parentProductCategory.setCreator(JwtUtils.getLoginUserId());
                        parentProductCategory.setCreatorName(JwtUtils.getLoginUsername());
                        this.save(parentProductCategory);
                        productCategory.setParentId(parentProductCategory.getId());
                    }
                }else{
                    productCategory.setParentId(-1L);
                }
                productCategory.setCreateTime(LocalDateTime.now());
                productCategory.setCreator(JwtUtils.getLoginUserId());
                productCategory.setCreatorName(JwtUtils.getLoginUsername());

                ProductCategory category = list.stream().filter(t->t.getName().equals(productCategory.getName())).findFirst().orElse(null);
                if(category != null){
                    productCategory.setId(category.getId());
                }
                this.saveOrUpdate(productCategory);
            }
        }
    }
}
